CraftTweaker reference:
	https://crafttweaker.readthedocs.io/en/latest/

=====
Check if a mod is loaded
=====

//if MinecraftCoderPack is loaded
if(loadedMods.contains("mcp")){
    print("success!!!");
}

ModLoaderPreprocessor

The modLoaded Preprocessor only executes a script, if a certain mod is present.

You call the modLoaded Preprocessor by adding #modloaded modID to your script file, with modID being the modId you want to check for:
Example: #modloaded minecraft

You can also provide multiple modID’s:
#modloaded minecraft tconstruct will only be executed if minecraft AND tconstruct are loaded.

If you added this preprocessor to a script, it will only be executed if the provided modID’s are present, in other words if the 
respecting mods are loaded.

=====
Stack Size:
=====
	
val apple = <minecraft:apple>;
val bucket = <minecraft:bucket>;

//prints 64
print(apple.maxStackSize);

//sets apples Max Stack size to 32
apple.maxStackSize = 32;

//prints 32
print(apple.maxStackSize);

//sets apples Max Stack size to Bucket's Max Stack size
apple.maxStackSize = bucket.maxStackSize;

//prints 16
print(apple.maxStackSize);

=====

Custom name: ingredients:

item.onlyWithTag(NBTTag);
<minecraft.iron_pickaxe>.onlyWithTag({display: {Name: "Pickle the Pickleberry"}});

Custom name: outputs:

item.withTag(NBTTag);
<minecraft:iron_pickaxe>.withTag({display: {Name: "Pickle the Pickleberry"}})

=====

Tooltips

Adding or removing a tooltip is really easy:
All you need is an item (or oreDict or similar), in other words, an IIngredient.
Clearing tooltips

This removes ALL tooltips from the item

item.clearTooltip();

Normal Tooltips

This adds tT as tooltip to item.

item.addTooltip(tT);

<minecraft:chest>.addTooltip("Storage, what can I say more?");

item is a IIngredient
tT is a string
Shift Tooltips

This adds a tooltip, that will only be visible when you hold shift.

item.addShiftTooltip(tT);

<minecraft:chest>.addShiftTooltip("STORAGE!!!");

item is a IIngredient
tT is a string
Markup

The world is colorful, and so should be all of our tooltips. You can also nest these options, should you with to (if you wanted a green text, that is strikethrough)
Coloring a String

You can apply one of the 16 colors to your string

format.black
format.darkBlue
format.darkGreen
format.darkAqua
format.darkRed
format.darkPurple
format.gold
format.gray
format.darkGray
format.blue
format.green
format.aqua
format.red
format.lightPurple
format.yellow
format.white

<minecraft:stick>.addTooltip(format.green("This one wasn't ripe"));

Formatting a String

You can apply different formats to your String should you wish to:

format.obfuscated
format.bold
format.strikethrough
format.underline
format.italic

<minecraft:stick>.addShiftTooltip(format.strikethrough("This is a bad tooltip"));


=====
Furnace
=====

Crafttweaker allows you to Add and Remove Furnace recipes and change the fuel value of items.

There are 2 ways to remove Furnace recipes, being:

furnace.remove(output)
furnace.remove(output, input);

The first syntax is more flexible with the recipes that are removed and will remove all Furnace recipes that output the output given.
The second syntax is more strict with the recipes that are removed and will remove all Furnace recipes that output the output given and has an input of input.

There also is a third way of removing furnace recipes, though this one will remove ALL furnace recipes registered in the game.

furnace.removeAll();

Addition

There are 2 commands for adding furnace recipes:

furnace.addRecipe(output, input);
furnace.addRecipe(output, input, xp);

The first syntax will add a Furnace recipe that will give 0 xp on smelt.
The second syntax will add a Furnace recipe that will give xp xp on smelt.

Fuel: Set

The command for setting fuel values is:

furnace.setFuel(input, burnTime);

This will set the burn value of input to burnTime.

Setting the burnTime to 0 will stop the input from being a fuel item.

Fuel: Get

The command for retrieving an item’s fuel value is:

furnace.getFuel(item); 

This will return the burn value as an Integer

Examples
Removal

This will remove all Furnace recipes that outputs <minecraft:glass>.

furnace.remove(<minecraft:glass>);

This will remove all Furnace recipes <minecraft:quartz> that use <minecraft:quartz_ore> as an input.

furnace.remove(<minecraft:quartz>, <minecraft:quartz_ore>);

Addition

This will add a Furnace recipe that will output a <minecraft:golden_apple> when a <minecraft:apple> is smelted.

furnace.addRecipe(<minecraft:golden_apple>, <minecraft:apple>);

This will add a Furnace recipe that will output a <minecraft:speckled_melon> when a <minecraft:melon> is smelted and will give the player 1500 xp points.

furnace.addRecipe(<minecraft:speckled_melon>, <minecraft:melon>, 1500);

Fuel

This will set the Fuel value of <minecraft:rotten_flesh> to 100.

furnace.setFuel(<minecraft:rotten_flesh>, 100);

=====

When writing the exactly same command more than 10 times, with only 1 Parameter changing, I’ll use a loop.

So, instead of always typing out the functions, I declare one array containing all items and iterate through that one.

import crafttweaker.item.IIngredient;

val Array = [
    item1,
    item2,
    item3,
    ...
] as IIngredient[];


for item in Array{
    recipes.remove(item);
}

=====
Seeds
=====

Seeds are things you get from punching tall grass.
Print all seeds to the log

This command will print all registered seeds to the log.

Needs to be performed by a player or console, cannot be written in a zs-file.

1.12
/ct seeds

pre-1.12
/mt seeds

Add a seed drop

Adds item as seed drop.

vanilla.seeds.addSeed(item);

item is a weightedItemStack. What does that mean? It simply means that you need to give it a percentage like this:

//adds carrots with a weight of 1
vanilla.seeds.addSeed(<minecraft:carrot> % 100);

Remove a seed drop

Stops item from being a seed drop.

vanilla.seeds.removeSeed(item);

item is an IIngredient.

=====
Item Transformers
=====

Item Transformers transform your crafting inputs upon crafting.
This can range from damaging the item up to returning a completely different item.
Importing the package

It might be required for you to import the package if you encounter any issues (like casting an Array), so better be safe than sorry and add the import.
import crafttweaker.item.IItemTransformer;


val item = <minecraft:apple>;

//Item won't be consumed and will be placed in your inventory upon crafting.
transformedItem = item.giveBack();

//item will be consumed but will return the specified item to your inventory upon crafting.
transformedItem = item.giveBack(<minecraft:potato>);

//item will be replaced with the specified item, which will instead go to the crafting slot
transformedItem = item.transformReplace(<minecraft:potato>);

//damages the item by 1
transformedItem = item.transformDamage();

//damages the item by the given value
transformedItem = item.transformDamage(3);

//item will be consumed, no matter what.
transformedItem = item.noReturn();

//Causes multiple items to be consumed.
transformedItem = item.transformConsume(3);

=====
Tutorial:Advanced Recipes
=====

So far we have learned about how to add or remove simple recipes. But what if the inputs and outputs also involve damage values or NBT tags?

-- NBT Tag in output

It is possible to define both damage or an NBT tag as output. Let's take a pickaxe as our toy for this tutorial:

val stick = <minecraft:stick>;
val pick = <minecraft:stone_pickaxe>;
val damagedPick = pick.withDamage(10);
val stickedPick = pick.withTag({display: {Name: "Sticked pick", Lore: ["This pick", "Has been sticked"]}});

recipes.addShaped(damagedPick, [[pick, stick]]);
recipes.addShaped(stickedPick, [[pick, stick], [stick, stick]]);

Crafting the pick with 1 or 3 sticks as in the recipe will give you an item with the appropriate damage and name/lore on it, respectively.
Input conditions

You can also require the input to contain certain NBT tags. Say, you make a recipe that requires our sticked pick. Let's modify our file:

val stick = <minecraft:stick>;
val pick = <minecraft:stone_pickaxe>;
val damagedPick = pick.withDamage(10);
val stickedPick = pick.withTag({display: {Name: "Sticked pick", Lore: ["This pick", "Has been sticked"]}});

recipes.addShaped(damagedPick, [[pick, stick]]);
recipes.addShaped(stickedPick, [[pick, stick], [stick, stick]]);

val stonedPick = pick.withTag({display: {Name: "Stoned pick", Lore: ["This pick", "Has been experimenting too much"]}});
val onlyStickedPick = pick.onlyWithTag({display: {Name: "Sticked pick"}});
val cobble = <minecraft:cobblestone>;
recipes.addShaped(stonedPick, [[onlyStickedPick, cobble], [cobble, cobble]]);

What about the lore part in our sticked pick? Since your condition only contains the name, the lore part is ignored - when setting a 
condition on the data tag, MineTweaker only cares about the contents that you specified and ignores everything else.

Note the difference between withTag and onlyWithTag. withTag is for an output and is the exact tag that will be output. onlyWithTag is for 
input and sets a condition. Applying withTag on an input has no effect on the recipe.

Other conditions exist too:

myItem.onlyDamaged(); // only accepts damaged items
myItem.onlyDamageAtLeast(15); // only accepts items with a damage of at least 15
myItem.onlyDamageAtMost(100); // only accepts items with a damage of at most 100
myItem.onlyDamageBetween(15, 100); // only accepts items with a damage between 15 and 100

Multiple conditions can be added to a single ingredient, too:

myItem.onlyDamaged().onlyWithTag({display: {Name: "Sticked pick"}});

-- Output reuse and transformations

Since MineTweaker 3.0.2, it is now possible to reuse items, return empty buckets to the crafting grid (or whatever item you want) or damage 
items upon crafting.

We could for instance make a recipe to get more sticks out of wood by using an axe:

recipes.addShapeless(<minecraft:stick> * 3, [<minecraft:stone_axe>, <ore:woodPlanks>]);

Nice. But the stone axe gets consumed, and that is sort of annoying. We can fix this with the reuse modifier:

recipes.addShapeless(<minecraft:stick> * 3, [<minecraft:stone_axe>.reuse(), <ore:plankWood>]);

Great! We can reuse the axe. Now what if we also wanted the axe to be damaged when you use it?

recipes.addShapeless(<minecraft:stick> * 3, [<minecraft:stone_axe>.transformDamage(), <ore:plankWood>]);

We can also deal more than 1 damage upon crafting:

recipes.addShapeless(<minecraft:stick> * 3, [<minecraft:stone_axe>.transformDamage(4), <ore:plankWood>]);

Imagine we'd want to make a recipe to turn dirt into grass by combining dirt, a water bucket and wheat. We could make this recipe:

recipes.addShapeless(<minecraft:grass>, [<minecraft:dirt>, <minecraft:water_bucket>, <minecraft:wheat>]);

However, crafting this will consume the bucket. We can tell MineTweaker to return the empty bucket afterwards:

recipes.addShaped(<minecraft:grass>, [[
	<minecraft:dirt>,
	<minecraft:water_bucket>.transformReplace(<minecraft:bucket>),
	<minecraft:wheat>
]]);

Now, crafting a grass block will return the empty crafting bucket in the crafting grid.

Sometimes mods define their own behavior when you use their items while crafting. Likewise, Minecraft will return you an empty bucket when 
you use it in a crafting recipe. If you don't want that, you can tell the item to not return anything at all:

recipes.addShaped(<minecraft:grass>, [[
	<minecraft:dirt>,
	<minecraft:water_bucket>.noReturn(),
	<minecraft:wheat>
]]);

If you want to give something back, but not in the crafting inventory, you can also use giveBack. GiveBack can be used without arguments, 
in which case it will return the original item, or it can be used with an item, in which case that item will be given back into the 
player inventory:

recipes.addShaped(<minecraft:grass>, [[
	<minecraft:dirt>,
	<minecraft:water_bucket>.giveBack(<minecraft:iron_ore> * 3),
	<minecraft:wheat>
]]);

GiveBack will usually also have the side-effect of suppressing mod item return behavior. It may thus be a handy alternative to the 
transformReplace modifier in those cases.

-- Function recipes

When adding a recipe, you may also supply an additional argument, which is a custom function. This function can programmatically 
determine the output of your recipe.

To demonstrate how this works, let's make a recipe that repairs a stone pickaxe when you craft it with cobblestone. The output of our 
recipe depends on the pickaxe that is provided (its damage), thus a regular recipe won't work in this case.

Let's start by adding the function to it:

recipes.addShapeless(<minecraft:stone_pickaxe>, [<minecraft:stone_pickaxe>, <minecraft:cobblestone>], function(output, inputs, crafting) {
  // to be implemented
}

Now we need to look at the value of the pickaxe. In order to retrieve the actual values of the inputs, we need to mark them with a name, and 
MineTweaker will store it in the inputs list:

recipes.addShapeless(<minecraft:stone_pickaxe>, [<minecraft:stone_pickaxe>.marked("pick"), <minecraft:cobblestone>], 
	function(output, inputs, crafting) {
  // to be implemented. inputs.pick now contains the pickaxe used as input
}

Then it's just a matter of writing the code to fix the pickaxe:

recipes.addShapeless(<minecraft:stone_pickaxe>, [<minecraft:stone_pickaxe>.anyDamage().marked("pick"), <minecraft:cobblestone>], 
	function(output, inputs, crafting) {
  // the max is there to make sure that the damage doesn't go negative
  // fixes 25 damage per cobblestone
  return inputs.pick.withDamage(max(0, inputs.pick.damage - 25));
});

=====
